package com.freesky.biz.rights.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.freesky.biz.rights.domain.RightsActivityEntity;
import com.freesky.biz.rights.domain.RightsBusiEntity;
import com.freesky.biz.rights.mapper.RightsActivityMapper;
import com.freesky.biz.rights.mapper.RightsBusiMapper;
import com.freesky.biz.rights.pojo.LotteryItemPo;
import com.freesky.biz.rights.pojo.LotteryPrizePo;
import com.freesky.biz.rights.pojo.RightsBusiVo;
import com.freesky.biz.rights.service.IRightsBusiService;
import com.freesky.common.constant.CacheConstants;
import com.freesky.common.constant.LotteryConstants;
import com.freesky.common.constant.UserConstants;
import com.freesky.common.core.domain.AjaxResult;
import com.freesky.common.core.redis.RedisCache;
import com.freesky.common.utils.HashIdUtils;
import com.freesky.common.utils.RandomID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;


@Service
public class RightsBusiServiceImpl extends ServiceImpl<RightsBusiMapper, RightsBusiEntity>  implements IRightsBusiService {

    @Autowired
    private RightsBusiMapper rightsBusiMapper;

    @Autowired
    private RightsActivityMapper rightsActivityMapper;

    @Autowired
    private RedisCache redisCache;


    @Override
    public boolean checkNameUnique(RightsBusiEntity entity) {
        RightsBusiEntity info = rightsBusiMapper.checkNameUnique(entity.getBusiName());
        if((info != null) && !info.getId().equalsIgnoreCase(entity.getId())){
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    @Override
    public int auditBusi(String busiId, String auditFlag, String auditReason) {
        return rightsBusiMapper.auditBusi(busiId,auditFlag,auditReason);
    }

    @Override
    public int deleteRightsBusByIds(String[] ids) {
        rightsBusiMapper.deleteRightsBusByIds(ids);
        return 1;
    }

    @Override
    public String generalBusiId() {
        String encrypt = "";
        int loop = 0;
        while(loop<=10){
            encrypt = HashIdUtils.encode(Long.parseLong(RandomID.generate9()));
            if(this.getById(encrypt) == null){
                break;
            }
            loop = loop + 1;
        }
        return encrypt;
    }

    @Override
    public AjaxResult cacheSync(String id) {
        RightsBusiEntity rightsBusi = rightsBusiMapper.selectById(id);
        if(rightsBusi == null ){
            return AjaxResult.error("活动不存在！");
        }

        redisCache.deleteObject(CacheConstants.RIGHTS_BUSI_KEY + id);

        String lotteryKey = StrUtil.format(LotteryConstants.LOTTERY,rightsBusi.getId());
        if("2".equalsIgnoreCase(rightsBusi.getStatus())){
            Collection<String> keys = redisCache.keys(lotteryKey +":*");
            redisCache.deleteObject(keys);
            redisCache.deleteObject(lotteryKey);
            return AjaxResult.success("已同步缓存!");
        }

        String defaultItem = "";
        LambdaQueryWrapper<RightsActivityEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(RightsActivityEntity::getDelFlag,"0");
        queryWrapper.eq(RightsActivityEntity::getBusiId,id);
        List<RightsActivityEntity> rightsActivityList = rightsActivityMapper.selectList(queryWrapper);

        BigDecimal totalPercent = BigDecimal.ZERO;

        int totalDefaultItem = 0;
        //抽奖，校验概率和要1，同时默要有一个默认选项
        if("2".equalsIgnoreCase(rightsBusi.getBusiType())){
            for(RightsActivityEntity rightsActivityEntity : rightsActivityList){
                //totalPercent = totalPercent + rightsActivityEntity.getPercent().doubleValue();
                totalPercent = totalPercent.add(rightsActivityEntity.getPercent());
                System.out.println("totalPercent = " + totalPercent+"," + rightsActivityEntity.getPercent().doubleValue());
                if(rightsActivityEntity.getDefaultItem().intValue() == 1){
                    totalDefaultItem = totalDefaultItem + 1;
                }
            }
            System.out.println("totalPercent = " + totalPercent.doubleValue());

            if(totalPercent.doubleValue() != 1.0){
                return AjaxResult.error("抽奖的概率总和要为1");
            }
            if(totalDefaultItem != 1){
                return AjaxResult.error("默认选项只能设一个,建议设成概率最高的哪个!");
            }
        }
        Collection<String> keys = redisCache.keys(lotteryKey +":*");
        redisCache.deleteObject(keys);
        redisCache.deleteObject(lotteryKey);

        List<LotteryItemPo> lotteryItemPoList = new ArrayList<>();
        for(RightsActivityEntity rightsActivityEntity : rightsActivityList){
            LotteryItemPo lotteryItemPo = new LotteryItemPo();
            LotteryPrizePo lotteryPrizePo = new LotteryPrizePo();
            BeanUtil.copyProperties(rightsActivityEntity,lotteryItemPo,false);
            BeanUtil.copyProperties(rightsActivityEntity,lotteryPrizePo,false);
            lotteryItemPoList.add(lotteryItemPo);
            if(rightsActivityEntity.getDefaultItem()==1){
                defaultItem = rightsActivityEntity.getId();
                String lotteryDefaultItemkey = StrUtil.format(LotteryConstants.DEFAULT_LOTTERY_ITEM,rightsBusi.getId());
                redisCache.setCacheObject(lotteryDefaultItemkey, JSON.toJSONString(lotteryItemPo));
            }
            String lotteryPrizekey = StrUtil.format(LotteryConstants.LOTTERY_PRIZE,rightsBusi.getId(),lotteryPrizePo.getId());
            setLotteryPrizeToRedis(lotteryPrizekey,lotteryPrizePo);
        }
        //缓在设置
        String lotteryItemkey = StrUtil.format(LotteryConstants.LOTTERY_ITEM,rightsBusi.getId());
        redisCache.setCacheObject(lotteryItemkey, JSON.toJSONString(lotteryItemPoList));
        setLotteryToRedis(lotteryKey,rightsBusi,defaultItem);
        return AjaxResult.success("已同步缓存!");
    }

    @Override
    public AjaxResult resetSync(String id) {
        RightsBusiEntity rightsBusiVo = rightsBusiMapper.selectById(id);
        if(rightsBusiVo == null ){
            return AjaxResult.error("活动不存在！");
        }

        DateTime curDate = DateUtil.date();

        //按天计算
        DateTime dayStart = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysStart(),"yyyy-MM-dd HH:mm:ss");
        DateTime dayEnd = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysEnd(),"yyyy-MM-dd HH:mm:ss");

        //按周
        if("W".equalsIgnoreCase(rightsBusiVo.getTimeType())){
            //（1代表周一，2代表周二，依此类推，7代表周日）
            Set<String> timeDaysSet = new HashSet<>();
            timeDaysSet.addAll(Arrays.asList(rightsBusiVo.getTimeDays().split(",")));
            String days = String.valueOf(DateUtil.dayOfWeek(curDate));

            dayStart = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysStart(),"yyyy-MM-dd HH:mm:ss");
            dayEnd = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysEnd(),"yyyy-MM-dd HH:mm:ss");

        } else if("M".equalsIgnoreCase(rightsBusiVo.getTimeType())){
            Set<String> timeDaysSet = new HashSet<>();
            timeDaysSet.addAll(Arrays.asList(rightsBusiVo.getTimeDays().split(",")));
            String days = String.valueOf(DateUtil.dayOfMonth(curDate));

            dayStart = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysStart(),"yyyy-MM-dd HH:mm:ss");
            dayEnd = DateUtil.parse(DateUtil.format(curDate,"yyyy-MM-dd") +" "+rightsBusiVo.getDaysEnd(),"yyyy-MM-dd HH:mm:ss");
        }  else if("D".equalsIgnoreCase(rightsBusiVo.getTimeType())){

        } else {
            dayStart = DateUtil.date(rightsBusiVo.getStartTime());
            dayEnd = DateUtil.date(rightsBusiVo.getEndTime());
        }

        String startDt = DateUtil.format(dayStart,"yyyy-MM-dd HH:mm:ss");
        String endDt = DateUtil.format(dayEnd,"yyyy-MM-dd HH:mm:ss");

        rightsBusiMapper.resetBusi(id, startDt, endDt);
        rightsActivityMapper.resetActivity(id,startDt,endDt);
        return AjaxResult.success("已重置数量!");
    }


    private void setLotteryToRedis(String key, RightsBusiEntity rightsBusi,String defaultItem) {
        System.out.println("setLotteryToRedis,key:"+key);
        redisCache.hset(key, "id", rightsBusi.getId());
        redisCache.hset(key, "busiName", rightsBusi.getBusiName());
        redisCache.hset(key, "totalCoupons", rightsBusi.getTotalCoupons());
        redisCache.hset(key, "leftCoupons", (rightsBusi.getTotalCoupons() - rightsBusi.getUsedCoupons()));
        redisCache.hset(key, "defaultPrizeId", defaultItem);
    }

    private void setLotteryPrizeToRedis(String key, LotteryPrizePo lotteryPrize) {
        System.out.println("setLotteryPrizeToRedis,key:"+key);
        redisCache.hset(key, "id", lotteryPrize.getId());
        redisCache.hset(key, "busiId", lotteryPrize.getBusiId());
        redisCache.hset(key, "activityName", lotteryPrize.getActivityName());
        redisCache.hset(key, "amt", lotteryPrize.getAmt());
        redisCache.hset(key, "totalCoupons", lotteryPrize.getTotalCoupons());
        redisCache.hset(key, "leftCoupons", (lotteryPrize.getTotalCoupons() - lotteryPrize.getUsedCoupons()));
    }
}
